{
 COPYRIGHT (C) 1984-1989 Apple Computer,Inc.
 All rights reserved
}

UNIT IconPick;

{ Icon Resource Picker }

{ This is the Icon resource picker.  This picker is very similar to all other pickers.
	The general scheme is that a List structure is created whose cells
	contain the ID's of this resource type.  A drawproc is installed in the List
	record which is called to display the resource.  Obviously, graphical resources
	are drawn as is, but descriptions of other types can be displayed also (usually
	in a one-dimensional list). }

INTERFACE

USES	MemTypes, QuickDraw, OSIntf, ToolIntf, PackIntf,
			ResEd;

PROCEDURE EditBirth(thing: Handle; dad: ParentHandle);
PROCEDURE PickBirth(t: ResType; dad: ParentHandle);
PROCEDURE DoEvent(VAR evt: EventRecord; pick: PickHandle);
PROCEDURE DoInfoUpdate(oldID, newID: INTEGER; pick: PickHandle);
PROCEDURE DoMenu(menu, item: INTEGER; pick: PickHandle);

IMPLEMENTATION

CONST
	listCellSizeH = $40;
	listCellSizeV = $40;
	theScrollBar	= 15;
	
	{ Needs to be 2 wide so that I can always tell a 2d list from a normal text list. }
	minIconsPerRow = 2;
	ICONMinWindowWidth = (minIconsPerRow * listCellSizeH) + theScrollBar;
	ICONMinWindowHeight = listCellSizeV;
	
	ICONResourceSize = 128;

{$R-}

PROCEDURE EditBirth(thing: Handle; dad: ParentHandle);

	BEGIN
	END;

{ *********************************************************************************** }

{ Returns the width and the iconsPerRow. }
FUNCTION GetWidth (VAR iconsPerRow: INTEGER): INTEGER;

VAR
	width: INTEGER;

BEGIN
width := PickStdWidth;
IF width > ICONMinWindowWidth THEN
	BEGIN
	iconsPerRow := (width - theScrollBar) DIV listCellSizeH;
	width := (iconsPerRow * listCellSizeH) + theScrollBar;
	END
ELSE
	BEGIN
	width := ICONMinWindowWidth;
	iconsPerRow := minIconsPerRow;
	END;
GetWidth := width;
END;

{ *********************************************************************************** }

FUNCTION GetHeight: INTEGER;

VAR
	height: INTEGER;

BEGIN
height := PickStdRows * DefaultListCellSize;
IF height > ICONMinWindowHeight THEN
	height := (height DIV listCellSizeV) * listCellSizeV
ELSE
	height := ICONMinWindowHeight;
GetHeight := height;
END;

{ *********************************************************************************** }

PROCEDURE PickBirth(t: ResType; dad: ParentHandle);

VAR
	pick: PickHandle;
	myWindow: WindowPtr;
	from, myTitle: STR255;
	cSize: Cell;
	iconsPerRow: INTEGER;

BEGIN
IF (t <> 'ICON') THEN
	EXIT (Pickbirth);									{ This only works for ICON resources. }
	
GetStr(fromStr, miscStrings, from); { Get ' from ' }
myTitle := 'ICONs';
ConcatStr (myTitle, from);
myWindow := WindSetup(GetWidth (iconsPerRow), GetHeight, myTitle, dad^^.name);

IF myWindow <> NIL THEN
	BEGIN
	{ Get the memory for my data structure. }
	pick := PickHandle(NewHandle(SIZEOF(PickRec)));

	BubbleUp (Handle(pick));					{ Move it out of the way. }
	HLock (Handle(pick));							{ Lock it down so that I can dereference it. }

	WITH pick^^ DO
		BEGIN
		father := dad; 									{ Back ptr to dad }
		fName := dad^^.name;
		wind := myWindow; 							{ Directory window }
		rebuild := FALSE;
		pickID := ResedID; 							{ Get my resource ID }
		rType := 'ICON'; 								{ Resource type that I understand }
		rNum := CurResFile; 						{ Owner res file }
		rSize := ICONResourceSize;

		WITH WindowPeek(myWindow)^ DO
			BEGIN
			windowKind := ResedID;				{ Get my resource ID }
			refCon := ORD(pick);					{ Save the data structure for later use. }
			END;

		cSize.h := listCellSizeH;
		cSize.v := listCellSizeV;
		instances := WindList(myWindow, iconsPerRow, cSize, ResedID);
		
		scroll := instances^^.vScroll;
		
		LDoDraw(FALSE, instances);							{ Don't draw it as it is built - too slow. }
		nInsts := BuildType('ICON', instances); { Fill in the list with the ids of the resources. }
		LSetSelect(true, Cell(0), instances);		{ Select the first icon. }
		LDoDraw(true, instances);								{ Next time, draw them. }

		{ Need to update here to avoid the following:	The window is activated and the
		user types a character which causes the list to scroll.  The activate event is processed
		first and draws and hilights the first item.	The key down is processed next and scrolls
		the window which has only one item drawn.  An update comes along which includes all but
		the first item (which was updated by LActivate).	The display is left partially updated. }
		BeginUpdate(myWindow);
		LUpdate(myWindow^.visRgn, instances);
		EndUpdate(myWindow);
		END;

	HUnlock(Handle(pick));
	END;
END;

{ Everything except the grow box is taken care of for us by PickEvent.}
PROCEDURE DoEvent(VAR evt: EventRecord; pick: PickHandle);

VAR
	windPtr: WindowPtr;

BEGIN
{ Must do our own grow box manipulation so that the min size is set correctly. }
IF (evt.what = mouseDown) & (FindWindow(evt.where, windPtr) = inGrow) THEN
	GrowMyWindow (ICONMinWindowWidth, ICONMinWindowHeight, windPtr, pick^^.instances)
ELSE
	PickEvent(evt, pick);
END;

{ Everything is taken care of for us by PickInfoUp }
PROCEDURE DoInfoUpdate(oldID, newID: INTEGER; pick: PickHandle);

BEGIN
PickInfoUp(oldID, newID, pick);
END;

PROCEDURE DoMenu(menu, item: INTEGER; pick: PickHandle);

VAR
	 len, id: INTEGER;
	 tempH: Handle;
	 theCell: Cell;
BEGIN
{ Since we loaded all of the icons to draw them, we need to release them when we close the window. }
IF (menu = fileMenu) & (item = closeItem) THEN
	BEGIN
	{ Must do the PassMenu here even though it is done again in PickMenu so that there are no
		child windows open using the resources that I am about to free. }
	PassMenu(fileMenu, closeItem, ParentHandle(pick));
	
	BubbleUp(Handle(pick));
	HLock(Handle(pick));
	WITH pick^^ DO
		BEGIN
		UseResFile(rNum);		{ Make sure that we have the correct file. }
		theCell := Cell(0);	{ Start at the first cell. }
		SetResLoad (FALSE);	{ Don't load them in - we are trying to get rid of them! }
		REPEAT							{ Loop through all of the cells. }
			len := 2;					{ Get the id from the cell. }
			LGetCell(@id, len, theCell, instances);
			IF len > 0 THEN
				BEGIN
				tempH := Get1Res ('ICON', id);	{ Get the resource if it is loaded. }
				IF tempH <> NIL THEN						{ If not null then it was loaded. }
					ReleaseResource (tempH);			{ Toss it if it isn't changed. }
				END;
 		UNTIL NOT LNextCell (TRUE, TRUE, theCell, instances);
 		SetResLoad (TRUE);	{ Always restore this! }
		END;
	END;

{ Everything else is taken care of for us by PickMenu. }
PickMenu(menu, item, pick);	{ Do the normal picker stuff. }
END;

END.
